    
#include "object.h"

;
cGameObject::cGameObject()
{
    m_position = INTPOINT(0, 0);
    m_size = INTPOINT(0, 0);
    m_velocity = FLOATPOINT(0.0f, 0.0f);
    m_name = std::string("__NULL");

    m_state = STATE_ERROR;
    m_collide = COLLIDE_ERROR;
    m_type = TYPE_ERROR;
    //m_pCurrentObject = NULL;
}

cGameObject::~cGameObject()
{
    //if (m_vObjList.size() != 0)
    //{
    //    m_vObjList.clear();
    //}
}

/// create a new object
/*void cGameObject::newObject(INTPOINT pos, INTPOINT size, unsigned int type, string name)
{
    if (name == string("__NULL"))
    {
        name = string("obj" + m_vObjList.size());
    }

    OBJECT * obj = new OBJECT(pos, size, name);
    obj->velocity = FLOATPOINT(0.0f, 0.0f);
    obj->type = type;
    obj->state = 0;
    obj->collide = 0;

    m_vObjList.push_back(obj);
}*/

/// remove an object by name (if it exists)    
/*bool cGameObject::removeObjectByName(const char * name)
{
    return removeObjectByName(string(name));
}*/

/// remove an object by name (if it exists)    
/*bool cGameObject::removeObjectByName(string name)
{
    if (m_vObjList.size() != 0)
    {
        return false;
    }

    for (int i = 0; i < (int)m_vObjList.size(); i++)
    {
        if (m_vObjList[i]->name == name)
        {
            // this is a temporary method
            // TODO: make it remove it for real
            m_vObjList[i]->name = "null";
            return true;
        }
    }

    return false;
}*/

/// Update all objects
/*void cGameObject::updateObjects()
{
    if (m_vObjList.size() == 0)
        return;

    for (int i = 0; i < (int)m_vObjList.size(); i++)
    {
        //if (m_vObjList[i]->state == STATE_IDLE && m_vObjList[i]->type == TYPE_DYNAMIC)
        //{
        //    m_vObjList[i]->velocity.Y += 0.5f;
        //}
        if (m_vObjList[i]->type == TYPE_DYNAMIC)
        {
            if (m_vObjList[i]->collide != COLLIDE_BOTTOM) m_vObjList[i]->velocity.Y += 0.5f;

            if (m_vObjList[i]->velocity.X > 5.0f) m_vObjList[i]->velocity.X = 5.0f;
            if (m_vObjList[i]->velocity.Y > 5.0f) m_vObjList[i]->velocity.Y = 5.0f;

            m_vObjList[i]->pos.X += m_vObjList[i]->velocity.X;
            m_vObjList[i]->pos.Y += m_vObjList[i]->velocity.Y;
            
            if (m_vObjList[i]->velocity.X > 0) m_vObjList[i]->velocity.X--;
            if (m_vObjList[i]->velocity.X < 0) m_vObjList[i]->velocity.X++;
            //if (m_vObjList[i]->velocity.Y > 0) m_vObjList[i]->velocity.Y--; //there is gravity
            if (m_vObjList[i]->velocity.Y < 0) m_vObjList[i]->velocity.Y++;
        }
    }
}*/

/// Set size of current object
void cGameObject::setSize(int sizeX, int sizeY)
{
    setSize(INTPOINT(sizeX, sizeY));
}

/// Set size of current object
void cGameObject::setSize(const INTPOINT size)
{
    this->m_size = size;
}

/// Set position of current object
void cGameObject::setPos(int posX, int posY)
{
    setPos(INTPOINT(posX, posY));
}

/// Set position of current object
void cGameObject::setPos(const INTPOINT pos)
{
    this->m_position = pos;
}

void cGameObject::addPos(const INTPOINT add)
{
    addPos(add.X, add.Y);
}

void cGameObject::addPos(int addX, int addY)
{
    this->m_position.X += addX;
    this->m_position.Y += addY;
}


/// Get size of current object
INTPOINT cGameObject::getSize()
{
    return this->m_size;
}

/// Get position of current object
INTPOINT cGameObject::getPos()
{
    return this->m_position;
}


/// Set name of current object
void cGameObject::setName(string name)
{
    this->m_name = name;
}

/// Set name of current object
void cGameObject::setName(const char *name)
{
    setName(string(name));
}

/// Get name of current object
string cGameObject::getName()
{
    return this->m_name;
}

void cGameObject::setType(unsigned int type)
{
    this->m_type = type;
}

unsigned int cGameObject::getType()
{
    return this->m_type;
}

void cGameObject::setState(unsigned int state)
{
    this->m_state = state;
}

unsigned int cGameObject::getState()
{
    return this->m_state;
}

void cGameObject::setCollide(unsigned int collide)
{
    this->m_collide = collide;
}

unsigned int cGameObject::getCollide()
{
    return this->m_collide;
}

/// checks if objA is colliding with objB
unsigned int cGameObject::isColliding(cGameObject * objA, cGameObject * objB)
{
    //if (!(objA->m_type == TYPE_STATIC || objB->m_type == TYPE_STATIC))
    //    return 0;

    if (objA->m_collide != COLLIDE_NONE && objA->m_velocity.Y == 0.0f)
        return objA->m_collide;

    //bool result = collideMethodA(objA, objB);

    if (collideMethodA(objA, objB))
    {
        //objA->m_position.X -= (int)(objA->m_velocity.X * 1.1f);
        //objA->m_position.Y -= (int)(objA->m_velocity.Y * 1.1f);
        //objA->m_velocity = FLOATPOINT(0.0f, 0.0f);

        if (objA->m_velocity.Y > 0.0f)
        {
            if (objA->m_position.X > objB->m_position.X + objB->m_size.X)
            {
                objA->m_collide = COLLIDE_RIGHT;
                objA->m_velocity.X = 0.0f;
                objA->m_position.X = objB->m_position.X + objB->m_size.X;
            }
            else if (objA->m_position.X + objA->m_size.X < objB->m_position.X)
            {
                objA->m_collide = COLLIDE_LEFT;
                objA->m_velocity.X = 0.0f;
                objA->m_position.X = objB->m_position.X - objA->m_size.X;
            }
            else
            {
                objA->m_collide = COLLIDE_TOP;
                objA->m_velocity.Y = 0.0f;
                objA->m_position.Y = objB->m_position.Y - objA->m_size.Y;
            }
        }
        else if (objA->m_velocity.Y < 0.0f)
        {
            objA->m_collide = COLLIDE_BOTTOM;
            objA->m_velocity.Y = 0.0f;
            objA->m_position.Y = objB->m_position.Y + objB->m_size.Y;
        }

        /*
        if (objA->m_velocity.X > 0.0f)
        {
        }
        else if (objA->m_velocity.X < 0.0f)
        {
        }
        */

        /*if (objA->pos.Y + objA->size.Y > objB->pos.Y)
        {
            if (objA->pos.X + objA->size.X > objB->pos.X && objA->velocity.Y == 0)
            {
                objA->pos.X = objB->pos.X + objA->size.X;
                objA->collide = COLLIDE_RIGHT;
            }
            else if (objA->pos.X < objB->pos.X + objB->size.X && objA->velocity.Y == 0)
            {
                objA->pos.X = objB->pos.X - objB->size.X;
                objA->collide = COLLIDE_LEFT;
            }
            else
            {
                objA->pos.Y = objB->pos.Y - objA->size.Y;
                objA->collide = COLLIDE_BOTTOM;
            }
        }
        else
        {
            objA->pos.Y = objB->pos.Y + objB->size.Y;
            objA->collide = COLLIDE_TOP;
        }*/
    }
    else
        objA->m_collide = COLLIDE_NONE;

    return objA->m_collide;
}

/// checks if m_currentObject is colliding with &obj
unsigned int cGameObject::isCollidingWith(cGameObject * obj)
{
    return collideMethodA(this, obj);
}


/// Set if current object can collide
void cGameObject::setCanCollide(bool value)
{
    if (!value)
        this->m_state = STATE_CANTCOLLIDE;
    else
        this->m_state = STATE_IDLE;
}

/// Get if current object can collide
bool cGameObject::getCanCollide()
{
    if (this->m_state != STATE_CANTCOLLIDE)
        return true;
    return false;
}


/// Check if object is moving
bool cGameObject::isObjectMoving()
{
    // check if the object is of the dynamic type and then if its really moving
    if (this->m_type == TYPE_DYNAMIC && (this->m_velocity.X != 0.0f || this->m_velocity.Y != 0.0f))
        return true;

    return false;
}
    
/// Set current objects velocity
void cGameObject::setVelocity(FLOATPOINT velocity)
{
    if (this->m_type == TYPE_DYNAMIC)
        this->m_velocity = velocity;
}

/// Set current objects velocity
void cGameObject::setVelocity(float velX, float velY)
{
    setVelocity(FLOATPOINT(velX, velY));
}

void cGameObject::setVelocityX(float velX)
{
    this->m_velocity.X = velX;
}

void cGameObject::setVelocityY(float velY)
{
    this->m_velocity.Y = velY;
}

void cGameObject::addVelocity(FLOATPOINT addVel)
{
    addVelocity(addVel.X, addVel.Y);
}

void cGameObject::addVelocity(float addX, float addY)
{
    this->m_velocity.X += addX;
    this->m_velocity.Y += addY;
}

void cGameObject::addVelocityX(float addX)
{
    this->m_velocity.X += addX;
}

void cGameObject::addVelocityY(float addY)
{
    this->m_velocity.Y += addY;
}

/// Get current objects velocity
FLOATPOINT cGameObject::getVelocity()
{
    return this->m_velocity;
}


bool cGameObject::collideMethodA(cGameObject * objA, cGameObject * objB)
{
    bool X, Y;
    X = Y = false;

    if ((objA->m_position.X + objA->m_size.X) > (objB->m_position.X) && 
        (objA->m_position.X) < (objB->m_position.X + objB->m_size.X))
    {
        X = true;
    }
    
    if ((objA->m_position.Y + objA->m_size.Y) > (objB->m_position.Y) && 
        (objA->m_position.Y) < (objB->m_position.Y + objB->m_size.Y))
    {
        Y = true;
    }

    if (X && Y)
    {
        return true;
    }

    return false;
}

bool cGameObject::collideMethodB(cGameObject * objA, cGameObject * objB)
{
    return false;
}